package com.spade.dsms.controller;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.spade.dsms.controller.viewobject.UserVO;
import com.spade.dsms.error.BusinessException;
import com.spade.dsms.error.EmBusinessError;
import com.spade.dsms.response.CommonReturnType;
import com.spade.dsms.service.UserService;
import com.spade.dsms.service.model.UserModel;
import org.apache.tomcat.util.security.MD5Encoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

/**
 * @author Weikang  Wang
 * @program: com.spade.dsms.controller
 * @description: 用户控制器
 * @date 2019/11/5 10:30
 */
@RestController
public class UserController {

    public static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private HttpServletRequest httpServletRequest;

    /**
     * 获取用户信息
     *
     * @param id 用户id
     * @return 特定的返回值类型
     * @throws BusinessException 业务异常
     */
    @RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)
    public CommonReturnType getUser(@RequestParam(name = "id") Integer id) throws BusinessException {
        UserModel userModel = userService.getUserInfo(id);
        if (null == userModel) {
            throw new BusinessException(EmBusinessError.USER_NOT_EXIST);
        }
        UserVO userVO = convertToUserVO(userModel);
        return CommonReturnType.create(userVO);
    }

    /**
     * 用户获取otp短信接口
     *
     * @param phone 手机号
     * @return 特殊值
     */
    @RequestMapping(value = "/getOtp")
    public CommonReturnType getOtp(@RequestParam(name = "phone") String phone) {
        // 1.需要按照一定的规则生成otp验证码
        Random random = new Random();
        // 随机数取值[0,99999)
        int randomInt = random.nextInt(99999) + 10000;
        String otpCode = String.valueOf(randomInt);

        // 2.将otp验证码同对应用户的手机号关联(使用httpsession / Redis)
        httpServletRequest.getSession().setAttribute(phone, otpCode);

        // 3.将otp验证码通过短信通道发送给用户（需要服务）
        System.out.println("手机号：" + phone + ", 验证码：" + otpCode);
        logger.info("手机号：phone:{}，验证码：otpCode:{}", phone, otpCode);

        return CommonReturnType.create(null);
    }

    /**
     * 用户注册接口
     *
     * @param otpCode 验证码
     * @param phone   手机号
     * @param name    姓名
     * @param gender  类型
     * @param age     年龄
     * @return 特殊值
     */
    @PostMapping(value = "/register")
    public CommonReturnType register(@RequestParam(name = "otpCode") String otpCode,
                                     @RequestParam(name = "phone") String phone,
                                     @RequestParam(name = "name") String name,
                                     @RequestParam(name = "gender") Integer gender,
                                     @RequestParam(name = "age") Integer age,
                                     @RequestParam(name = "password") String password) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        // 获取验证码
        String sessionCode = (String) this.httpServletRequest.getSession().getAttribute(phone);
        // 判断用户验证码是否正确
        if (StringUtils.equals(sessionCode, otpCode)) {
            logger.error("短信验证码错误");
        }
        UserModel userModel = new UserModel();
        userModel.setUserName(name);
        userModel.setGender(gender.byteValue());
        userModel.setAge(age);
        userModel.setPhone(phone);
        // 密码MD5加密后存储
        userModel.setPassword(this.encodeByMd5(password));
        userService.register(userModel);

        return CommonReturnType.create("SUCCESS");
    }

    /**
     * 转换类
     *
     * @param userModel 用户信息
     * @return userVO
     */
    private UserVO convertToUserVO(UserModel userModel) {
        if (null == userModel) {
            return null;
        }
        UserVO userVO = new UserVO();
        userVO.setId(userModel.getId());
        userVO.setAge(userModel.getAge());
        userVO.setUserName(userModel.getUserName());
        userVO.setGender(userModel.getGender());
        userVO.setPhone(userModel.getPhone());
        return userVO;
    }

    /**
     * MD5加密算法：利用java自带的MessageDigest类实现MD5加密
     *
     * @param str 字符串
     * @return String
     * @throws NoSuchAlgorithmException     异常
     * @throws UnsupportedEncodingException 异常
     */
    public String encodeByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        // 确定计算方法
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        BASE64Encoder base64Encoder = new BASE64Encoder();
        // 加密字符串
        return base64Encoder.encode(md5.digest(str.getBytes("utf-8")));
    }

    /**
     * MD5 加密算法
     *
     * @param str 需要加密的信息
     * @return Base64密文
     * @throws NoSuchAlgorithmException     异常
     * @throws UnsupportedEncodingException 异常
     */
    public String encode(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        byte[] md5s = MessageDigest.getInstance("MD5").digest(str.getBytes("utf-8"));
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(md5s);
    }
}
